import Router from 'koa-router';
import mongoose from 'mongoose';
import assert from 'assert';
import moment from 'moment';

const Aggregation = mongoose.model('Aggregation');
const Message = mongoose.model('Message');
const Group = mongoose.model('Group');

const router = new Router({
  prefix: '/api/aggregation',
});

async function aggregateConcatCount(beginAt, endAt) {
  const content = await Message.aggregate([
    {
      $match: {
        fromSocialId: { $exists: true },
        createdAt: {
          $gte: beginAt,
          $lt: endAt,
        },
      },
    },
    { $group: { _id: '$fromUser' } },
    { $group: { _id: null, contactCount: { $sum: 1 } } },
    { $project: { _id: 0 } },
  ]);

  return content.length > 0 ? content[0].contactCount : 0;
}

async function aggregateAssistantReplyCount(beginAt, endAt) {
  const assistantGroup = await Group.findOne({ name: '助教' });
  if (!assistantGroup) return [];

  return Message.aggregate([
    {
      $match: {
        createdAt: {
          $gte: beginAt,
          $lt: endAt,
        },
        fromSocialId: { $exists: true },
      },
    },
    {
      $lookup: {
        from: 'users',
        localField: 'fromUser',
        foreignField: '_id',
        as: 'fromUserEntity',
      },
    },
    {
      $match: {
        'fromUserEntity.group': assistantGroup._id,
      },
    },
    {
      $group: {
        _id: { fromUser: '$fromUser', toChannel: '$toChannel' },
        userName: { $first: '$fromUserEntity.username' },
      },
    },
    {
      $group: { _id: '$userName', replyCount: { $sum: 1 } },
    },
    {
      $project: { username: { $arrayElemAt: ['$_id', 0] }, replyCount: 1, _id: 0 },
    },
  ]);
}

router.post('/summary', async (ctx) => {
  const { aggregationAt } = ctx.request.body;

  assert(aggregationAt, 'aggregationAt not found');
  const aggregationAtYMD = moment(aggregationAt).format('YYYY-MM-DD');

  let aggregation = await Aggregation.findOne({ aggregationAt: aggregationAtYMD });

  if (aggregation) {
    ctx.body = aggregation;
  } else {
    const beginAt = moment(aggregationAt)
      .startOf('day')
      .toDate();
    const endAt = moment(aggregationAt)
      .endOf('day')
      .toDate();

    const contactCount = await aggregateConcatCount(beginAt, endAt);
    let assistantReply = await aggregateAssistantReplyCount(beginAt, endAt);

    assistantReply = assistantReply.map((reply) => {
      const name = (reply.username || '').replace('admin:', '');
      return {
        replyCount: reply.replyCount,
        assistantName: name,
      };
    });

    aggregation = new Aggregation({
      aggregationAt: aggregationAtYMD,
      contactCount,
      assistantReply,
    });

    // aggregation.assistantReply.
    await aggregation.save();
    ctx.body = aggregation;
  }
});

export default router;